package com.ry.novel.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ry.novel.enums.NovelConst;
import com.ry.novel.model.dto.BookInfo;
import com.ry.novel.model.entity.Book;
import com.ry.novel.service.BookIndexService;
import com.ry.novel.service.BookService;
import com.ry.novel.mapper.BookIndexMapper;
import com.ry.novel.model.dto.BookIndexInfo;
import com.ry.novel.model.dto.condition.BookIndexQuery;
import com.ry.novel.model.entity.BookIndex;
import com.ry.novel.utils.DateUtil;
import com.ry.novel.utils.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author ry
 * @since 2022-03-27 17:14
 **/
@Slf4j
@Service
public class BookIndexServiceImpl implements BookIndexService {
    @Autowired
    private BookIndexMapper bookIndexMapper;

    @Autowired
    private BookService bookService;

    @Override
    public Page<BookIndexInfo> queryBookIndexInfo(BookIndexQuery query) {
        Page<BookIndex> page = new Page<>(query.getPage(), query.getSize());
        Page<BookIndexInfo> infoPage = new Page<>(query.getPage(), query.getSize());
        QueryWrapper<BookIndex> wrapper = new QueryWrapper<>();

        if (null != query.getBookId()) {
            wrapper.eq("book_id", query.getBookId());
        }
        if (null != query.getState()) {
            wrapper.eq("state", query.getState());
        }
        if (null != query.getIndexName()) {
            wrapper.like("index_name", query.getIndexName());
        }
        if (null != query.getWordCount()) {
            wrapper.gt("word_count", query.getWordCount());
        }
        if (null != query.getCreateTime()) {
            wrapper.gt("create_time", query.getCreateTime());
        }
        if (null != query.getUpdateTime()) {
            wrapper.lt("update_time", query.getUpdateTime());
        }
        wrapper.orderByDesc("create_time");

        bookIndexMapper.selectPage(page, wrapper);

        List<BookIndexInfo> infos = page
                .getRecords()
                .stream()
                .map(entity ->
                        getBookIndexInfo(entity)
                ).collect(Collectors.toList());

        infoPage.setRecords(infos);
        infoPage.setTotal(page.getTotal());

        return infoPage;
    }

    /**
     * 更新章节信息
     *
     * @param info
     */
    @Override
    public void updateIndex(BookIndexInfo info) {
        log.info(info.toString());
        BookIndex bookIndex = new BookIndex();
        if (info.getContent() != null) {
            //更新章节信息
            bookIndex.setWordCount(StringUtil.getStrValidWordCount(info.getContent()));
            //将换行符和空白符转义
            String content = info
                    .getContent()
                    .replaceAll("\\n", "<br />")
                    .replaceAll("\\s", "&nbsp;");
            bookIndex.setContent(content);

            //更新小说信息
            //如果修改了章节内容，才需要更新小说字数
            BookIndex originIndex = bookIndexMapper.selectById(info.getId());
            //章节的原字数
            Integer originIndexWordCount = originIndex.getWordCount();
            BookInfo bookInfo = bookService.queryById(info.getBookId());
            //减去原章节的字数，加上新的章节字数
            bookInfo.setWordCount(bookInfo.getWordCount() - originIndexWordCount + StringUtil.getStrValidWordCount(info.getContent()));


            //更新章节信息
            bookService.updateBook(bookInfo);
        }
        bookIndex.setId(info.getId());
        bookIndex.setReason(info.getReason());
        bookIndex.setIndexName(info.getIndexName());
        bookIndex.setState(info.getState());
        bookIndex.setUpdateTime(LocalDateTime.now().toString());


        bookIndexMapper.updateById(bookIndex);
    }

    /**
     * 根据bookId查询最新章节的num
     *
     * @param bookId
     * @return
     */
    public Integer lastIndexNum(Long bookId) {
        QueryWrapper<BookIndex> wrapper = new QueryWrapper<>();
        //index_num最大的那一条记录
        wrapper.eq("book_id", bookId);
        wrapper.orderByDesc("index_num");
        wrapper.last("limit 1");


        BookIndex bookIndex = bookIndexMapper.selectOne(wrapper);


        return null == bookIndex ? 0 : bookIndex.getIndexNum();
    }

    @Override
    public void addIndex(BookIndexInfo bookIndexInfo) {
        BookIndex entity = new BookIndex();
        entity.setBookId(bookIndexInfo.getBookId());
        entity.setState(NovelConst.BOOK_INDEX_REVIEW);

        //先查出上一章节的num
        entity.setIndexNum(lastIndexNum(bookIndexInfo.getBookId()) + 1);
        entity.setIndexName(bookIndexInfo.getIndexName());
        entity.setCharge(NovelConst.BOOK_INDEX_IS_FREE);
        entity.setWordCount(StringUtil.getStrValidWordCount(bookIndexInfo.getContent()));
        entity.setCreateTime(LocalDateTime.now().toString());
        entity.setUpdateTime(LocalDateTime.now().toString());

        //将换行符和空白符转义
        String content = bookIndexInfo
                .getContent()
                .replaceAll("\\s", "&nbsp;")
                .replaceAll("\\n", "<br />")
                .replace("<script>", "")
                .replace("</script>", "");
        entity.setContent(content);

        bookIndexMapper.insert(entity);

        BookInfo queryById = bookService.queryById(bookIndexInfo.getBookId());
        BookInfo bookInfo = new BookInfo();
        bookInfo.setId(queryById.getId());
        bookInfo.setLastIndexName(entity.getIndexName());
        bookInfo.setWordCount(queryById.getWordCount() + entity.getWordCount());
        bookInfo.setLastIndexId(entity.getId());
        bookInfo.setLastIndexUpdateTime(entity.getUpdateTime());
        bookService.updateBook(bookInfo);
    }

    @Override
    public void deleteIndex(Long id) {
        //查询当前章节属于那一本书
        BookIndexInfo bookIndexInfo = queryBookIndexById(id);
        BookInfo bookInfo = bookService.searchById(bookIndexInfo.getBookId());
        if (bookInfo != null){
            long result = bookInfo.getWordCount() - bookIndexInfo.getWordCount();
            bookInfo.setWordCount(result);
            bookService.updateBook(bookInfo);
        }

        bookIndexMapper.deleteById(id);
    }

    @Override
    public BookIndexInfo queryBookIndexById(Long id) {
        BookIndex entity = bookIndexMapper.selectById(id);
        BookIndexInfo bookIndexInfo = new BookIndexInfo();
        bookIndexInfo.setId(entity.getId());
        bookIndexInfo.setBookId(entity.getBookId());
        BookInfo bookInfo = bookService.searchById(entity.getBookId());
        if (bookInfo != null) {
            bookIndexInfo.setBookName(bookInfo.getBookName());
        }
        String content = entity
                .getContent()
                .replaceAll("<br&nbsp;/>","<br />");
        bookIndexInfo.setContent(content);
        bookIndexInfo.setState(entity.getState());
        bookIndexInfo.setIndexNum(entity.getIndexNum());
        bookIndexInfo.setIndexName(entity.getIndexName());
        bookIndexInfo.setCharge(entity.getCharge());
        bookIndexInfo.setWordCount(entity.getWordCount());
        bookIndexInfo.setCreateTime(DateUtil.format(entity.getCreateTime()));
        bookIndexInfo.setUpdateTime(DateUtil.format(entity.getUpdateTime()));

        return bookIndexInfo;
    }

    @Override
    public List<BookIndexInfo> queryBookIndexByBookId(Long bookId) {
        QueryWrapper<BookIndex> wrapper = new QueryWrapper<>();
        wrapper.eq("book_id", bookId);
        List<BookIndex> bookIndices = bookIndexMapper.selectList(wrapper);
        List<BookIndexInfo> infos = bookIndices.stream().map(entity -> getBookIndexInfo(entity)).collect(Collectors.toList());

        return infos;
    }

    private BookIndexInfo getBookIndexInfo(BookIndex entity) {
        BookIndexInfo bookIndexInfo = new BookIndexInfo();
        bookIndexInfo.setId(entity.getId());
        BookInfo bookInfo = bookService.searchById(entity.getBookId());
        if (bookInfo != null) {
            bookIndexInfo.setBookId(entity.getBookId());
            bookIndexInfo.setBookName(bookInfo.getBookName());
        }else{
            bookIndexInfo.setBookName("当前书籍已被删除");
        }
        String content = entity
                .getContent()
                .replaceAll("&nbsp;"," ")
                .replaceAll("<br/>","\n")
                .replaceAll("<br />","\n");
        bookIndexInfo.setContent(content);
        bookIndexInfo.setState(entity.getState());
        bookIndexInfo.setIndexNum(entity.getIndexNum());
        bookIndexInfo.setIndexName(entity.getIndexName());
        bookIndexInfo.setCharge(entity.getCharge());
        bookIndexInfo.setWordCount(entity.getWordCount());
        bookIndexInfo.setCreateTime(DateUtil.format(entity.getCreateTime()));
        bookIndexInfo.setUpdateTime(DateUtil.format(entity.getUpdateTime()));

        return bookIndexInfo;
    }
}
